/**************************************************************************//**
 * @file           main.c
 * @version        V1.0
 * $Revision:      1 $
 * $Date:          2017/01/04 $
 * @brief          Main function
 * @Author         Jeffrey Kang
 * @ContactInfo    chkang@esmt.com.tw
 *
 * @note
 *
 * Copyright (C) 1998 Elite Semiconductor Memory Technology Corp.
 * All rights reserved.
 *
 ******************************************************************************/


#include <REG52.h>
#include "system_FE81001.h"

unsigned char cnt = 0;

unsigned char I2C_TX_Buffer[10] = {0};		// Transfer data buffer
unsigned char I2C_RX_Buffer[10] = {0}; 	// Receive data buffer




/**
 * @brief       delay function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void delay (int cnt )
{
	unsigned int i , j ;
	
	for(j=0 ; j<cnt ; j++)
	for( i = 0 ; i < 200 ; i++ ); 
	
}



/**
 * @brief       I2CSISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void I2CISR (void) interrupt ISR_I2C
{
	unsigned short int_stat;
	
	int_stat = (I2C->int_st[1] << 8) | I2C->int_st[0];
	
			
	/* FIFO full : read data here */
   if ((int_stat & 0x02) == 0x02){
	}
	
	/* Cmpl */
	else if ((int_stat & 0x0200) == 0x0200){
		I2C->int_st[1] |= 0x02;
			
	}
	
	/* FIFO empty : set data here */
	else if ((int_stat & 0x01) == 0x01){
	}
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
}


/**
 * @brief       IOConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void IOConfig()
{
	/* enable P0.4, P0.5 open drain */
	PORT_SetPAOpenDrain(BIT4 | BIT5);
	
	
	/* enable P0.4(SCL), P0.5(SDA) function */
	Set_PA4_SDA();
	Set_PA5_SCL();	
	
		/* Set PC7 input as button */
		PORT_SetPCInput(BIT7);

		/* Set PD1,PD2,PD3 output */
		PORT_SetPDPushPull(BIT1 | BIT2 | BIT3 );
}


/**
 * @brief       CLKConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void CLKConfig()
{
	/* enable GPIO clock */
	PORT_PAPBPCPD_Clock_Enable();
	
	/* enable I2C clock */
	En_I2C_clk();
	
}

/**
 * @brief       I2C_Master_Write	 function
 *
 * @param       data_ :  Transfer data
												len 		:		Length of	transfer buffer
												slave_address	:		Slavess address
 *
 * @return      None
 *
 * @details     1. 
 */

void I2C_Master_Write(unsigned char *data_ , unsigned char len , unsigned char slave_address )
{
	unsigned char  i ; 

	I2C->i2c_cmd = 0x05; // Reset I2C control 

	/* i2c setup */
	I2C->i2c_setup[0] = 0x05;         // Master = 1, Addressing = 0, IICEN = 1
	
	/* set slave address */
	I2C->slv_adr[0] = slave_address; 
	I2C->slv_adr[1] = 0x00;
	
	/* interrupt enable */
	I2C->int_en[0] = 0x00;            // ByteTrans = 0, Start = 0, Stop = 0, ArbLose = 0, AddrHit = 0, FIFOHalf = 0, FIFOFull = 0, FIFOEmpty = 1
	I2C->int_en[1] = 0x00;            // Cmpl = 1, ByteRecv = 0
	//INTC->int_gmask = 0x01;
	
	/* set i2c start */
	I2C->i2c_ctrl = 0x10;             // Phase_start = 1, Phase_addr = 0, Phase_data = 0, Phase_stop = 0, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x40) != 0x40){}
	I2C->int_st[0] = 0x40;
	
	/* set i2c slave address */
	I2C->i2c_ctrl = 0x08;             // Phase_start = 0, Phase_addr = 1, Phase_data = 0, Phase_stop = 0, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x08) != 0x08){}
	I2C->int_st[0] = 0x08;
	
	/* set i2c data */
	for(i=0 ; i<len ; i++)
	{
		I2C->i2c_ctrl = 0x04;             // Phase_start = 0, Phase_addr = 0, Phase_data = 1, Phase_stop = 0, Dir = 0 (master transmitter)
		I2C->datcnt = 1 ;
		I2C->i2c_dat = *(data_+i);
		I2C->i2c_cmd = 0x01;
	 while((I2C->int_st[0] & 0x80) != 0x80){}
	I2C->int_st[0] = 0x80;	
	}
	
	/* set i2c stop */
	I2C->i2c_ctrl = 0x02;             // Phase_start = 0, Phase_addr = 0, Phase_data = 0, Phase_stop = 1, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x20) != 0x20){}
	I2C->int_st[0] = 0x20;
	
}

/**
 * @brief       I2C_Master_Read	 function
 *
 * @param       data_ 			:  Transfer data
												len_W 		:		Length of	transfer buffer
												len_R 			:		Length of	receive buffer
												slave_address	:		Slavess address
 *
 * @return      None
 *
 * @details     1. 
 */

void I2C_Master_Read(unsigned char *data_ , unsigned char len_W ,unsigned char len_R , unsigned char slave_address)
{
	
	unsigned char  i ; 
//---------WRITE-------------------//

	I2C->i2c_cmd = 0x05; // Reset I2C
	
	/* i2c setup */
	I2C->i2c_setup[0] = 0x05;         // Master = 1, Addressing = 0, IICEN = 1
	
	/* set slave address */
	I2C->slv_adr[0] = slave_address;  //slave_address
	I2C->slv_adr[1] = 0x00;
	
	/* interrupt enable */
	I2C->int_en[0] = 0x00;            // ByteTrans = 0, Start = 0, Stop = 0, ArbLose = 0, AddrHit = 0, FIFOHalf = 0, FIFOFull = 0, FIFOEmpty = 1
	I2C->int_en[1] = 0x00;            // Cmpl = 1, ByteRecv = 0
	//INTC->int_gmask = 0x01;
	
	/* set i2c start */
	I2C->i2c_ctrl = 0x10;             // Phase_start = 1, Phase_addr = 0, Phase_data = 0, Phase_stop = 0, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x40) != 0x40){}
	I2C->int_st[0] = 0x40;
	
	/* set i2c slave address */
	I2C->i2c_ctrl = 0x08;             // Phase_start = 0, Phase_addr = 1, Phase_data = 0, Phase_stop = 0, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x08) != 0x08){}
	I2C->int_st[0] = 0x08;
	
	/* set i2c data */
	
	for(i=0 ; i<len_W ; i++)
	{
		I2C->i2c_cmd = 0x04;
		I2C->i2c_ctrl = 0x04;             // Phase_start = 0, Phase_addr = 0, Phase_data = 1, Phase_stop = 0, Dir = 0 (master transmitter)
		I2C->datcnt = 1 ;
		
		I2C->i2c_dat = *(data_+i);
		I2C->i2c_cmd = 0x01;
		while((I2C->int_st[0] & 0x80) != 0x80){}
		I2C->int_st[0] = 0x80;	
	}

//--------- READ-------------------//

	I2C->int_en[1] = 0x01;            // Cmpl = 1, ByteRecv = 0	
		
	/* i2c setup */
	I2C->i2c_setup[0] = 0x05;         // Master = 1, Addressing = 0, IICEN = 1
	
	/* set i2c configuration */
	I2C->datcnt   = 1;
	
	/* set slave address */
	I2C->slv_adr[0] = slave_address;
	I2C->slv_adr[1] = 0x00;
		
	/* set i2c start */
	I2C->i2c_ctrl = 0x10;             // Phase_start = 1, Phase_addr = 0, Phase_data = 0, Phase_stop = 0, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x40) != 0x40){}
	I2C->int_st[0] = 0x40;
	
	/* set i2c slave address */
	I2C->i2c_ctrl = 0x09;             // Phase_start = 0, Phase_addr = 1, Phase_data = 0, Phase_stop = 0, Dir = 1 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x08) != 0x08){}
	I2C->int_st[0] = 0x08;
	
	I2C->i2c_ctrl = 0x05;   
	I2C->datcnt = 1;	
	I2C->i2c_cmd = 0x01;
	
	for( i = 0 ;i<len_R ; i ++){
		
	while((I2C->int_st[1] & 0x01) != 0x01){} 
	I2C->int_st[1] |= 0x01;	
		
	I2C->i2c_ctrl = 0x01;
	
		if(i == len_R-1)
		{	
			I2C->i2c_cmd = 0x03; // cmd = 0x02 :ack  0x03 :nack
		}
		else
		{
				I2C->i2c_cmd = 0x02; // cmd = 0x02 :ack  0x03 :nack
		}
	
		I2C_RX_Buffer[i] =I2C->i2c_dat ;	
		
	}
		
	/* set i2c stop */
	I2C->i2c_ctrl = 0x02;             // Phase_start = 0, Phase_addr = 0, Phase_data = 0, Phase_stop = 1, Dir = 0 (master transmitter)
	I2C->i2c_cmd = 0x01;
	while((I2C->int_st[0] & 0x20) != 0x20){}
	I2C->int_st[0] = 0x20;
	
}

void I2C_Master_Config()
{
		CLKConfig();
		IOConfig();
		I2C_speed_400k_8M();
	
}

/**
 * @brief       main function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
int main (void)
{
	 I2C_Master_Config();
	
		PD1 = 1; // LED_G1 Off
		PD2 = 1 ; //LED_R Off
		PD3=  1;  // LED_G2  Off
	
	// Master Tx Test
	I2C_TX_Buffer[0] = 0x01;
	I2C_TX_Buffer[1] = 0x02;
	I2C_TX_Buffer[2] = 0x03;
  I2C_Master_Write(I2C_TX_Buffer,3,0x57);

	// Master Rx Test
	I2C_TX_Buffer[0] = 0x00; 
	I2C_Master_Read(I2C_TX_Buffer,1,2,0x57);  // Receive data in " I2C_RX_Buffer "
	
	
	
	while(1)
		
	{
			if( ( Get_PCx_input(7) )  == 0)
			{
						PD1 = 0; // LED_G1 On
						PD2 = 0 ; //LED_R On
						PD3= 0;  // LED_G2  On
				
			}
		else
		{
						PD1 = 1; // LED_G1 Off
						PD2 = 1 ; //LED_R Off
						PD3=  1;  // LED_G2  Off
		}
			
	}
}

